package com.iwhalecloud.bss.kite.cucc.service.order;

import java.util.*;
import java.util.stream.Collectors;

import com.iwhalecloud.bss.kite.common.util.*;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalKeyConsts;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import com.iwhalecloud.bss.kite.common.log.KiteLogger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.common.collect.Lists;
import com.iwhalecloud.bss.kite.client.api.reception.IServiceOfferService;
import com.iwhalecloud.bss.kite.client.dto.DataResult;
import com.iwhalecloud.bss.kite.client.vo.scene.ProdAttrModuleVO;
import com.iwhalecloud.bss.kite.client.vo.scene.ProdAttrVO;
import com.iwhalecloud.bss.kite.client.vo.scene.ProdRoleModuleVO;
import com.iwhalecloud.bss.kite.client.vo.scene.ProductModuleVO;
import com.iwhalecloud.bss.kite.client.vo.spec.ServiceOfferTypeVO;
import com.iwhalecloud.bss.kite.client.vo.spec.ServiceOfferVO;
import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.iwhalecloud.bss.kite.common.constant.ServiceOfferConsts;
import com.iwhalecloud.bss.kite.cucc.client.api.goods.IGoodsService;
import com.iwhalecloud.bss.kite.cucc.client.api.order.IBusinessChangeService;
import com.iwhalecloud.bss.kite.cucc.client.dto.goods.GoodsDTO;
import com.iwhalecloud.bss.kite.cucc.common.constant.CuccServiceOfferConsts;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalErrorConsts;
import com.iwhalecloud.bss.kite.cucc.service.scene.attr.CuccOperateInstAttrService;
import com.iwhalecloud.bss.kite.dataservice.cache.AttrValueCache;
import com.iwhalecloud.bss.kite.dataservice.cache.DcPublicCache;
import com.iwhalecloud.bss.kite.dataservice.cache.OfferDetailCache;
import com.iwhalecloud.bss.kite.dataservice.cache.ProductCache;
import com.iwhalecloud.bss.kite.dataservice.entity.DcPublic;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.OfferDetail;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.Product;
import com.iwhalecloud.bss.kite.dataservice.util.SplictUtil;
import com.iwhalecloud.bss.kite.manager.api.IOperateSceneInstService;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.inst.KiteAttr;
import com.iwhalecloud.bss.kite.manager.inst.KiteProdInst;
import com.iwhalecloud.bss.kite.manager.inst.KiteSceneInst;
import com.iwhalecloud.bss.kite.service.scene.attr.OperateInstAttrService;

import com.ztesoft.bss.base.entity.StaticAttrDO;
import com.ztesoft.bss.common.util.ContextUtil;

/**
 * Created by huanghaosheng on 2020/9/17 17:04
 */
@Service
public class BusinessChangeService implements IBusinessChangeService {

    @Autowired
    private IQuerySceneInstService querySceneInstService;

    @Autowired
    private OperateInstAttrService operateInstAttrService;

    @Autowired
    private IOperateSceneInstService operateSceneInstService;

    @Autowired
    private CuccOperateInstAttrService cuccOperateInstAttrService;

    @Autowired
    private IServiceOfferService serviceOfferService;

    @Autowired
    private IGoodsService goodsService;

    private static final String INSTANCETYPE = "10C";

    private static final String PROD_INSTANCETYPE = "10A";

    private static final String SOURCE = "0";

    private static final String WLW_PROD_CATEID = "20201217001";

    private static final String OPERATE_CHECK_MODIFY = "7000";

    private  final static String  COMMON_REGION_ID = "10000000";

    @Override
    public ProdAttrModuleVO dealProdAttrList(String sceneInstId, String custId, KiteProdInst kiteProdInst,
                                             String serviceOfferId, ProdAttrModuleVO prodAttrModule) {

        String provinceCode = ContextUtil.getLoginInfo().getUserInfo().getPostProvinceNbr();
        if (ServiceOfferConsts.SERVICE_OFFER_MODIFY.equals(serviceOfferId)
            // || CuccServiceOfferConsts.SERVICE_OFFER_OTHER_BUSINESS_CHANGE.equals(serviceOfferId)
            || (CuccServiceOfferConsts.SERVICE_OFFER_BUSINESS_CHANGE.equals(serviceOfferId)) && !LocalKeyConsts.PROVINCE_HEBEI.equals(provinceCode)) {
            // 如果service_control_scope中配置的mustEdit为T则将isEdit设置为T
            KiteProdInst inst = querySceneInstService.getProdInst(custId, kiteProdInst.getProdInstId());
            // fieldNameAndIsEdit 为service_control_scope中查出的数据,以FieldName值为key，isEdit值为value,用以记录，为之后取交集和设置是否可以编辑
            KiteSceneInst sceneInst = querySceneInstService.getSceneInst(sceneInstId);
            operateInstAttrService.getKiteInstAttrs(inst, inst.listAttrs(), sceneInst);
            if (KiteListUtils.isNotEmpty(inst.listAttrs())) {
                List<ProdAttrVO> prodAttrList = inst.listAttrs().stream()
                    .filter(m -> KiteStringUtils.equalsAny(m.getShowType(), KeyConsts.PROD_ATTR_SHOW_TYPE_D, KeyConsts.PROD_ATTR_SHOW_TYPE_M))
                    .map(this::transform).sorted(Comparator.comparing(this::orderIdToInt)).collect(Collectors.toList());

                prodAttrModule.setProdAttrList(prodAttrList);
            }
        } else {
            prodAttrModule = cuccOperateInstAttrService
                .processAttrs(sceneInstId, custId, kiteProdInst.getProdInstId(), serviceOfferId,
                    kiteProdInst.getProdId());
        }
        return prodAttrModule;
    }

    /**
     * {@link KiteAttr} to {@link ProdAttrVO}
     *
     * @param kiteAttr
     * @return
     */
    private ProdAttrVO transform(KiteAttr kiteAttr) {
        ProdAttrVO prodAttrVO = KiteBeanUtils.transform(kiteAttr, new ProdAttrVO());
        if (CollectionUtils.isNotEmpty(kiteAttr.getAttrValues())) {
            List<StaticAttrDO> staticAttrList = new ArrayList<>(kiteAttr.getAttrValues().size());
            kiteAttr.getAttrValues().forEach(kiteAttrValue -> {
                StaticAttrDO staticAttrDO = KiteBeanUtils.transform(kiteAttrValue, StaticAttrDO.class);
                staticAttrDO.setAttrValueDesc(kiteAttrValue.getAttrValueName());
                staticAttrList.add(staticAttrDO);
            });
            prodAttrVO.setAttrValues(staticAttrList);
        }
        return prodAttrVO;
    }

    private int orderIdToInt(ProdAttrVO v) {
        return Integer.parseInt(StringUtils.isEmpty(v.getOrderId()) ? "0" : v.getOrderId());
    }

    /**
     * Description: <br>
     * 生成产品对象
     *
     * @param prodId
     * @return <br>
     */
    @Override
    public ProductModuleVO genProductVO(String prodId) {
        ProductModuleVO vo = new ProductModuleVO();
        Product product = ProductCache.get(prodId);
        vo.setProdId(product.getProdId());
        vo.setProdName(product.getProdName());
        vo.setProdFuncType(product.getProdFuncType());
        return vo;
    }

    /**
     * Description: <br>
     * 生成产品对象
     *
     * @param prodInst
     * @return <br>
     */
    @Override
    public ProdRoleModuleVO genProductRoleVO(KiteProdInst prodInst) {
        ProdRoleModuleVO vo = new ProdRoleModuleVO();
        vo.setModuleName(prodInst.getProdName());
        vo.setProdId(prodInst.getProdId());
        vo.setProdRoleName(prodInst.getProdName());
        vo.setProdRoleId(prodInst.getRoleId());
        vo.setMinNum("0");
        vo.setMaxNum("1");
        vo.setOfferDetailId("-1");
        vo.setProdRoleId(prodInst.getRoleId());
        vo.setProdInstId(prodInst.getProdInstId());
        vo.setActionType(prodInst.getInstType().name());
        return vo;
    }

    @Override
    public void restoreScene(String serviceOfferId, String sceneInstId, String custId) {
        // 还原场景数据，当前serviceOfferId 能操作的实例数据需要还原为初始数据
        List<KiteProdInst> kiteProdInsts = querySceneInstService.listProdInsts(sceneInstId);
        String curSceneInstId = sceneInstId;
        String curServiceOfferId = serviceOfferId;
        if (KiteListUtils.isNotEmpty(kiteProdInsts)) {
            kiteProdInsts.forEach(kiteProdInst -> {
                ProdAttrModuleVO prodAttrModule = new ProdAttrModuleVO();
                prodAttrModule = dealProdAttrList(curSceneInstId, custId, kiteProdInst, curServiceOfferId,
                    prodAttrModule);
                List<ProdAttrVO> prodAttrVOList = prodAttrModule.getProdAttrList();
                if (KiteListUtils.isNotEmpty(prodAttrVOList)) {
                    List<KiteAttr> kiteAttrs = new ArrayList<>();
                    for (ProdAttrVO prodAttrVO : prodAttrVOList) {
                        KiteAttr kiteAttr = kiteProdInst.getAttr(prodAttrVO.getFieldName());
                        String value = kiteAttr.getValue();
                        kiteAttr.setValue(kiteAttr.getOldValue());
                        String valueDesc = kiteAttr.getOldValue();
                        if (!KiteStringUtils.isEmpty(value) && KeyConsts.DROPDOWN
                            .equals(kiteAttr.getAttrValueTypeId())) {
                            valueDesc = Optional.ofNullable(AttrValueCache.getAttrValue(kiteAttr.getAttrId(), value))
                                .map((attrValue) -> attrValue.getAttrValueDesc()).orElse("");
                        }
                        kiteAttr.setValueDesc(valueDesc);
                        kiteAttrs.add(kiteAttr);
                    }
                    // 统一执行完了之后，再统一将数据放到对象池
                    operateSceneInstService
                        .setAttrs(curSceneInstId, kiteProdInst.getInstType(), kiteProdInst.getInstId(), kiteAttrs);
                }
            });
        }
    }

    @Override
    public void checkSceneMutex(String serviceOfferId, List<String> serviceOfferIds) {
        // 判断互斥逻辑
        String curServiceOfferId = serviceOfferId;
        if (KiteListUtils.isNotEmpty(serviceOfferIds)) {
            serviceOfferIds.stream().forEach(serviceOffer -> {
                if (SplictUtil.isMutex(curServiceOfferId, serviceOffer)) { //校验当前操作类型是否互斥
                    LocalErrorConsts.BUSINESS_CHANGE_ERROR01.throwOut();
                }
            });
        }
    }

    @Override
    public List<ProdAttrVO> removeProdAttrVO(List<ProdAttrVO> prodAttrVOList) {
        Set<ProdAttrVO> prodAttrVOSet = new TreeSet<ProdAttrVO>(
            (o1, o2) -> o1.getFieldName().compareTo(o2.getFieldName()));
        prodAttrVOSet.addAll(prodAttrVOList);
        return new ArrayList<ProdAttrVO>(prodAttrVOSet);
    }

    @Override
    @KiteLogger(isWrite = true)
    public List<ServiceOfferTypeVO> queryServiceOfferInfo(String goodKu, String cateId, String custId,
                                                          String instanceType, String modifyType) {
        List<ServiceOfferTypeVO> serviceOfferTypeList = null;
        DataResult<List<ServiceOfferTypeVO>> serviceOfferTypeVOList;

        if (instanceType.equals(INSTANCETYPE)) { //instanceType为10C,做销售品修改
            List<String> objIds = Lists.newArrayList();
            objIds.add(goodKu);
            objIds.add(cateId);
            serviceOfferTypeVOList = serviceOfferService
                .listServiceOffersByObjIds(instanceType, objIds, SOURCE, "", "", "", "", custId, "", "");
            serviceOfferTypeList = serviceOfferTypeVOList.getResultObject();
        } else if (instanceType.equals(PROD_INSTANCETYPE)) { //instanceType为10A,做产品修改
            List<OfferDetail> offerDetails = OfferDetailCache.get(goodKu);
            List<String> prodIds = Lists.newArrayList();
            offerDetails.stream().forEach(offerDetail -> {
                prodIds.add(offerDetail.getObjId());
            });
            if (KiteListUtils.isNotEmpty(prodIds)) {
                List<String> prodIdList = prodIds.stream().distinct().collect(Collectors.toList());
                // 数字化多个产品合成一个产品（MV）跨域没有停开机业务，采用sku区分
                String prodId = (prodIdList.size() > 1 || Objects.nonNull(DcPublicCache.get("20210830101", cateId))) ? goodKu : prodIdList.get(0);
                List<String> objIds = Lists.newArrayList();
                objIds.add(prodId);
                objIds.add(cateId);
                serviceOfferTypeVOList = serviceOfferService
                    .listServiceOffersByObjIds(instanceType, objIds, SOURCE, "", "", "", "", custId, "", "");
                serviceOfferTypeList = serviceOfferTypeVOList.getResultObject();
                // checkForModify为资源核查变更,资源核查变更的operate_type=7000
                if(KiteStringUtils.isNotEmpty(modifyType) && "checkForModify".equals(modifyType)){
                    serviceOfferTypeList = serviceOfferTypeList.stream().filter(s->OPERATE_CHECK_MODIFY.equals(s.getOperateType())).collect(Collectors.toList());
                }else{
                    serviceOfferTypeList = serviceOfferTypeList.stream().filter(s->!OPERATE_CHECK_MODIFY.equals(s.getOperateType())).collect(Collectors.toList());
                }
            }
        }
        sortServiceOffer(serviceOfferTypeList, cateId);
        // 根据省份再做一次过滤(如果同一商品不同省份需要不同的二次类业务配置。可以在offer_service_rel表中的apply_region_id字段可以配置省份的编码。)
        filterByProvinceCode(serviceOfferTypeList);
        return serviceOfferTypeList;
    }

    public void filterByProvinceCode(List<ServiceOfferTypeVO> serviceOfferTypeList) {
        String provinceCode = ContextUtil.getLoginInfo().getUserInfo().getPostProvinceNbr();
        for (ServiceOfferTypeVO serviceOfferTypeVO : serviceOfferTypeList) {
            List<ServiceOfferVO> ServiceOfferList = serviceOfferTypeVO.getServiceOfferViews();
            ServiceOfferList.removeIf(serviceOfferVO -> !KiteStringUtils.equalsAny(serviceOfferVO.getApplyRegionId(), COMMON_REGION_ID, provinceCode));
        }
    }

    public String getPromotionOfferId(String catagoryId, List<String> offerIds) {
        String promotionOfferId = null;
        List<GoodsDTO> list = goodsService.queryGoodsListInCategroy(catagoryId, null);
        if (KiteListUtils.isNotEmpty(list)) {
            //如果只有1个，默认使用第一个
            if (list.size() == 1) {
                promotionOfferId = list.get(0).getGoodsSku();
            }
            //如果有多个，每个都查一次确认基础商品在哪个促销下面
            else {
                for (GoodsDTO goodsDTO : list) {
                    String goodsSkuList = goodsService.queryGoodKeyAttrs(goodsDTO.getGoodsSku()).getResultObject()
                        .get(0).getGoodsSku();
                    for (String o : offerIds) {
                        if (goodsSkuList.contains(o)) {
                            promotionOfferId = goodsDTO.getGoodsSku();
                            break;
                        }
                    }
                }
            }
        }
        return promotionOfferId;
    }

    private void sortServiceOffer(List<ServiceOfferTypeVO> serviceOfferTypeList, String cateId) {
        if (KiteListUtils.isEmpty(serviceOfferTypeList)) {
            return;
        }
        String provinceCode = ContextUtil.getLoginInfo().getUserInfo().getPostProvinceNbr();
        for (ServiceOfferTypeVO serviceOfferType : serviceOfferTypeList) {
            List<ServiceOfferVO> serviceOfferList = serviceOfferType.getServiceOfferViews();
            if (KiteListUtils.isEmpty(serviceOfferList)) {
                continue;
            }
            // 临时解决方案，某些商品的服务动作在某些省份值看见
            serviceOfferList.removeIf(serviceOffer ->{
                // pkey商品分裂，pcode是服务动作，getCodea配置省份编码
                List<DcPublic> dcPbulicList = DcPublicCache.getByPcode("20210509001", cateId, serviceOffer.getServiceOfferId());
                if (KiteListUtils.isNotEmpty(dcPbulicList)) {
                    boolean flag = true;
                    for (DcPublic dcPbulic :dcPbulicList) {
                        if (KiteStringUtils.isEqual(dcPbulic.getCodea(), provinceCode)) {
                            flag = false;
                        }
                    }
                    if(flag) {
                        return true;
                    }
                }
                return false;
            });


            Collections.sort(serviceOfferList, new Comparator<ServiceOfferVO>() {

                @Override
                public int compare(ServiceOfferVO o1, ServiceOfferVO o2) {
                    return o1.getSeq().compareTo(o2.getSeq());//根据第一个参数小于、等于或大于第二个参数分别返回负整数、零或正整数
                }
            });
        }
    }
}
